#include <QtGui/QApplication>
#include <qdeclarativeengine.h>
#include <qdeclarativecontext.h>
//#include <qdeclarativecomponent.h>
#include <qdeclarative.h>
#include <qdeclarativeitem.h>
#include <qdeclarativeview.h>

#include "logicmanager.h"
#include "networkmanager.h"
#include "userinfomodel.h"
#include "recordinfomodel.h"
#include "logicmanageradaptor.h"
void setupNetworkAndLogicConnection(NetworkManager *, LogicManager *);
void setupUiAndLogicConnection(QObject * uiWindow, LogicManagerAdaptor * logicManagerAdaptor);
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    NetworkManager *networkManager = new NetworkManager();
   // LogicManager *logicManager = new LogicManager();
    LogicManagerAdaptor *logicAdaptor = new LogicManagerAdaptor();
    QDeclarativeView view;

    QDeclarativeContext *ctxt = view.rootContext();
  //  ctxt->setContextProperty("currentDateTime", QDateTime::currentDateTime())
    ctxt->setContextProperty("contactNamesModel", logicAdaptor->m_userInfoModel);
    ctxt->setContextProperty("logicAdaptor", logicAdaptor);
    view.setSource(QUrl("qrc:qml/qml_ui.qml"));
    view.show();
    QObject *mainWnd = view.rootObject();

    // Setup Connection
    setupNetworkAndLogicConnection(networkManager, logicAdaptor->m_logicManager);
    setupUiAndLogicConnection(mainWnd,logicAdaptor);

    int appReuslt = app.exec();

    // Ui Disappear and wait logout response
    // TODO:


    // Logout finished
    delete logicAdaptor;
    delete networkManager;

    return appReuslt;
}

void setupNetworkAndLogicConnection(NetworkManager * networkManager, LogicManager * logicManager)
{
    QObject::connect(networkManager, SIGNAL(recieveServerData(QByteArray)),
                     logicManager, SLOT(onReceivedServerData(const QByteArray &)));
    QObject::connect(networkManager, SIGNAL(serverNotify(int)),
                     logicManager, SLOT(onServerNotify(int)));

    QObject::connect(logicManager, SIGNAL(sendServerData(const QByteArray &)),
                     networkManager, SLOT(onSendServerData(QByteArray)));


    QObject::connect(networkManager, SIGNAL(recieveData(QString, QByteArray)),
                     logicManager, SLOT(onReceivedData(const QString &, const QByteArray &)));
    QObject::connect(networkManager, SIGNAL(notify(QString, int)),
                     logicManager, SLOT(onNotify(const QString &, int)));

    QObject::connect(logicManager, SIGNAL(sendData(const QString &, const QByteArray &)),
                     networkManager, SLOT(onSendData(QString, QByteArray)));


}

void setupUiAndLogicConnection(QObject * uiWindow, LogicManagerAdaptor * logicManagerAdaptor)
{
    // Ui to Logic
    LogicManager *logicManager = logicManagerAdaptor->m_logicManager;
    QObject::connect(uiWindow, SIGNAL(closeWindow()),
                     logicManager, SLOT(onSendLogout()));
    QObject::connect(uiWindow, SIGNAL(sendMessage(const QString&, const QString&)),
                     logicManager, SLOT(onSendMessage(const QString &, const QString &)));
    QObject::connect(uiWindow, SIGNAL(stopChating(const QString&)),
                     logicManager, SLOT(onCloseConnection(const QString&)));
    QObject::connect(uiWindow, SIGNAL(login(const QString&)),
                     logicManager, SLOT(onSendLogin(const QString &)));


//    // Logic to Ui
//    QObject::connect(logicManager, SIGNAL(networkStatusChanged(eNetworkStatus)),
//                     uiWindow, SLOT(onNetworkStatusChanged(eNetworkStatus)));
//    QObject::connect(logicManager, SIGNAL(loginStatusReceived(eLoginStatus)),
//                     uiWindow, SLOT(onLoginResultReceived(eLoginStatus)));
//    QObject::connect(logicManagerAdaptor, SIGNAL(userListChanged(const QList<userInfo> &)),
//                     uiWindow, SLOT(onContactListUpdated(const QList<userInfo>&)));
//    QObject::connect(logicManagerAdaptor, SIGNAL(messageUpdated(const QString &, const QString &)),
//                     uiWindow, SLOT(onMessageUpdated(const QString&, const QString &)));

}
